package com.jubaozan.framework.sentinel.generator;

import cn.hutool.extra.spring.SpringUtil;
import java.lang.management.ManagementFactory;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Enumeration;
import java.util.UUID;
import lombok.RequiredArgsConstructor;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * @author jiangjinwu
 * @version 1.0
 * @since 2025/7/17 12:04
 */

@Slf4j
@Component("defaultInstanceIdGenerator")
public class DefaultInstanceIdGenerator implements InstanceIdGenerator {

    private final String instanceId;

    public DefaultInstanceIdGenerator() {
         this.instanceId = generateInstanceId();
    }

    @Override
    public String getInstanceId() {
        return instanceId;
    }

    private String generateInstanceId( ) {
        try {
            // 获取 IP 地址（优先使用非回环地址）
            String ip = getFirstNonLoopbackIpAddress();
            // 获取端口（从配置或环境变量中获取）
            int port = getServerPort( );

            // 格式：应用名-IP:端口
            return String.format("%s-%d", ip, port);
        } catch (Exception e) {
            // 异常情况下生成随机 ID
            return UUID.randomUUID().toString();
        }
    }

    private String getFirstNonLoopbackIpAddress() throws SocketException {
        Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
        while (interfaces.hasMoreElements()) {
            NetworkInterface ni = interfaces.nextElement();
            Enumeration<InetAddress> addresses = ni.getInetAddresses();
            while (addresses.hasMoreElements()) {
                InetAddress addr = addresses.nextElement();
                if (!addr.isLoopbackAddress() && addr instanceof Inet4Address) {
                    return addr.getHostAddress();
                }
            }
        }
        // 回退到本地主机名
        try {
            return InetAddress.getLocalHost().getHostAddress();
        } catch (UnknownHostException e) {
            throw new RuntimeException(e);
        }
    }

    private int getServerPort() {
        String port = SpringUtil.getProperty("server.port");;
        return Integer.parseInt(port);
    }
}
